package main

import (
	"MqttCloudProtocolServer/ProtocolServer/mqttlib"
	"MqttCloudProtocolServer/ProtocolServer/tcplib"
	"MqttCloudProtocolServer/protocols/go/checkonline"
	"MqttCloudProtocolServer/protocols/go/datareportjson"
	"MqttCloudProtocolServer/protocols/go/modbus"
	uint16regs "MqttCloudProtocolServer/protocols/go/uint16Regs"
	"MqttCloudProtocolServer/publiclib/dbcontrol"
	"os"

	//"MqttCloudProtocolServer/src/publiclib/logiclib"
	"io/ioutil"
	"net"
	"strings"
	"sync"
	"time"

	"github.com/wonderivan/logger"
)

//CloudServer 主类。main函数、服务等等均从此类启动。Start启动，Stop停止
type CloudServer struct {
	tcps         map[string]mqttlib.IOperator
	mqttConntion *mqttlib.MqttConnectionDef
	//configParam   *datamodel.ConfigParam
	configDBParam *dbcontrol.MqttserverControl
	isRunning     bool
	cmdListener   net.Listener
	MainCmd       chan string
}

var cloudServerContent *CloudServer

//GetMainClass 获得MainClass的单例实体
func GetMainClass() *CloudServer {
	if cloudServerContent == nil {
		cloudServerContent = new(CloudServer)
		//logiclib.CheckIsLog("protocol.log")
	}
	cloudServerContent.MainCmd = make(chan string)
	cloudServerContent.isRunning = true
	return cloudServerContent
}

//不使用
func (_this *CloudServer) startCommandThread() bool {
	listener, err := net.Listen("tcp", "127.0.0.1:2019")
	if err != nil {
		return false
	}
	confun := func() {
		_this.cmdListener = listener
		for {
			if conn, err := listener.Accept(); err != nil {
				logger.Alert("server :: accept error:", err)
				break
			} else {
				//为了不阻塞新的连接接入，采用协程接收数据
				go _this.receiveCommand(conn)
			}
		}
	}
	go confun()
	return true
}

//不使用
func (_this *CloudServer) receiveCommand(conn net.Conn) {
	var buffer = make([]byte, 1024)
	var retryCount = 0
	for _this.IsRunning() {
		if len, e := conn.Read(buffer); e != nil {
			logger.Debug("server :: read error:", e)
			time.Sleep(time.Second)
			retryCount++
			if retryCount > 5 {
				retryCount = 0
				conn.Close()
				return
			}
		} else {
			logger.Debug("server :: read data ")
			//logger.Info(string(buffer[:len]))
			cmd := string(buffer[:len])
			if strings.ToUpper(cmd) == "EXIT" {
				_, er := conn.Write([]byte("exit"))
				if er != nil {
					logger.Alert("command send error")
				}
				conn.Close()
				_this.cmdListener.Close()
				_this.Stop(true)
			} else {
				logger.Alert("command error")
			}
			retryCount = 0
		}
	}

}

//Start MainClass 启动解析、运行等工作。从构造函数中剥离，方便程序重启使用
//return: 启动是否成功
func (_this *CloudServer) Start() bool {
	//for _this.isRunning {
	//sleep
	//fmt.Println("what?")
	//}

	// var temp netoperator.IOperator
	// temp = new(netoperator.OperatorBase)
	// temp.SetKey("key1")
	// fmt.Println(temp.GetKey())
	// return true

	_this.isRunning = true
	//if !_this.startCommandThread() {
	//	logger.Error("监控进程启动失败")
	//	return false
	//}

	logger.Info("打开配置文件")
	if !_this.loadConfigFiles() {
		logger.Alert("Config file load error")
		return false
	}
	_this.tcps = make(map[string]mqttlib.IOperator)

	logger.Info("系统配置")

	if !_this.configMqttThread() {
		logger.Warn("配置MQTT线程出错")
		//logger.Warn(err)
	}
	if !_this.configTCPThread() {
		logger.Warn("配置TCP线程出错")
		//logger.Warn(err)
	}
	logger.Info("启动mqtt线程")
	if !_this.mqttThreadStart() {
		logger.Warn("启动mqtt线程出错")
		//logger.Warn(err)
	}
	logger.Info("启动tcp线程")
	if !_this.tcpThreadStart() {
		logger.Warn("启动tcp线程出错")
		//logger.Warn(err)
	}
	logger.Info("启动完毕，进入空循环")
	return true
}

//Stop CloudServer停止并释放资源
func (_this *CloudServer) Stop(isExit bool) {
	logger.Debug("STOP-0")
	_this.mqttConntion.Close()
	var muxLock sync.WaitGroup
	for _, item := range _this.tcps {
		logger.Debug(item.GetKey())
		muxLock.Add(1)
		go func(e mqttlib.IOperator, lock *sync.WaitGroup) {
			e.Close()
			lock.Done()
		}(item, &muxLock)
	}
	muxLock.Wait()
	logger.Debug("STOP-1")
	_this.tcps = make(map[string]mqttlib.IOperator)
	logger.Debug("STOP-2")
	//_this.res = false
	_this.isRunning = false
	if isExit {
		_this.MainCmd <- "EXIT"
	}
}

//Wait CloudServer阻塞
func (_this *CloudServer) Wait() {
	for {
		res := <-_this.MainCmd
		if strings.ToUpper(res) == "EXIT" {
			break
		}
	}
}

//Restart CloudServer重启
func (_this *CloudServer) Restart() {
	_this.Stop(false)
	_this.Start()

}

//IsRunning CloudServer监测是否在运行
func (_this *CloudServer) IsRunning() bool {
	return _this.isRunning
}

//读取配置文件
func (_this *CloudServer) loadConfigFiles() bool {
	str, _ := os.Getwd()
	logger.Info("当前路径：", str)
	_this.configDBParam = dbcontrol.CreateMqttserverControl()
	server, dberr := _this.configDBParam.GetAll()
	if server == nil {
		logger.Fatal("配置文件不存在")
		return false
	}
	if dberr != nil {
		logger.Alert(dberr)
		return false
	}

	if len(server) < 1 {
		return false
	}
	_this.configDBParam.Data = server[0]
	dberr = _this.configDBParam.GetChildrenTCPConf()
	if dberr != nil {
		logger.Alert(dberr)
		return false
	}
	if _this.configDBParam.ChildrenTCPConf != nil {
		for _, tcpConf := range _this.configDBParam.ChildrenTCPConf {
			dberr = tcpConf.GetChildrenMqttconf()
			if dberr != nil {
				logger.Alert(dberr)
				return false
			}
		}
	}
	return true

	/*var buffer []byte
	var err error
	//if buffer, err = _this.fileRead("config.json"); err != nil {
	if buffer, err = _this.fileRead("config\\config.json"); err != nil {
		logger.Alert(err)
		return false
	}

	obj := new(datamodel.ConfigParam)
	if err = json.Unmarshal(buffer, obj); err != nil {
		logger.Alert(err)
		return false
	} else if obj != nil {
		_this.configParam = obj
		return true
	}
	_this.configParam = nil
	return false*/
}

//配置MQTT线程
func (_this *CloudServer) configMqttThread() bool {
	mqtts := make(map[string]*mqttlib.MqttCSPareClass)
	for _, client := range _this.configDBParam.ChildrenTCPConf {
		if client.Data.Protocol > 1 {
			server := new(mqttlib.MqttCSPareClass)
			server.SetKey(client.Data.UUID)
			if len(client.ChildrenMqttconf) > 0 {
				server.Modify(client.ChildrenMqttconf[0].Data) //PS
			}
			server.SetReceive(_this.mqttReceiver)
			mqtts[server.GetKey()] = server
		}
	}
	_this.mqttConntion = new(mqttlib.MqttConnectionDef)
	_this.mqttConntion.SetKey("MQTT2TCP")
	_this.mqttConntion.Modify(_this.configDBParam.Data) //PS OK
	_this.mqttConntion.Modify(mqtts)
	return true
}

//配置TCP（协议服务）线程
func (_this *CloudServer) configTCPThread() bool {
	for _, client := range _this.configDBParam.ChildrenTCPConf {
		if client.Data.Protocol > 1 {
			var server mqttlib.IOperator
			switch client.Data.Protocol {
			case 2: //Direct 完全透传
				{
					//server2 := new(tcplib.TCPServerDirect)
					server2 := new(tcplib.TCPServer)
					server2.SetReceive(_this.tcpReceiver)
					server = server2
					break
				}
			case 3: //ModbusTCP ModbusRTU转ModbusTCP
				{
					server2 := new(tcplib.TCPServer)
					server2.SetReceive(_this.tcpReceiver)
					server = server2
					break
				}
			case 4: //ModbusRTU ModbusRTU直连（处理排队连接）
				{
					server2 := new(tcplib.TCPServer)
					server2.SetReceive(_this.tcpReceiver)
					server = server2
					break
				}
			case 5: //ModbusTCPDirect ModbusRTU转ModbusTCP不处理排队
				{
					//server2 := new(tcplib.TCPServerDirect)
					server2 := new(tcplib.TCPServer)
					server2.SetReceive(_this.tcpReceiver)
					server = server2
					break
				}
			case 6: //ModbusServer 移远方案，网关具备通讯管理
				{
					server2 := new(tcplib.ModbusServer)
					server = server2
					break
				}
			case 7: //ModbusRTUAnalysis 服务器通讯管理,服务器端协议解析
				{
					server2 := new(modbus.ModbusRTUAnalysis)
					server2.SetReceive(_this.tcpReceiver)
					server = server2
					break
				}
			case 8: //主动上传原始寄存器方案的Modbus通讯管理机，网关上报寄存器值
				{
					server2 := new(uint16regs.UInt16DataAnalysis)
					server2.SetReceive(_this.tcpReceiver)
					server = server2
					break
				}
			case 9: //主动上传原始数据的，网关上报最终数值
				{
					server2 := new(datareportjson.DataReportAnalysis)
					server2.SetReceive(_this.tcpReceiver)
					server = server2
					break
				}
			case 10: //仅检测最终状态
				{
					server2 := new(checkonline.CheckOnlineAnalysis)
					if client.ChildrenMqttconf != nil && len(client.ChildrenMqttconf) > 0 {
						server2.SetName(client.ChildrenMqttconf[0].Data.ClientName)
					} else {
						server2.SetName(client.Data.UUID)
					}
					//server2.SetReceive(_this.tcpReceiver)
					server = server2
					break
				}
			case 11: //ModbusTCPAnalysis 服务器通讯管理,服务器端协议解析
				{
					server2 := new(modbus.ModbusTCPAnalysis)
					server2.SetReceive(_this.tcpReceiver)
					server = server2
					break
				}
			}
			//server := new(tcplib.TCPServer)
			server.SetKey(client.Data.UUID)
			server.Modify(client.Data) //PS OK
			//server.SetReceive(_this.tcpReceiver)
			_this.tcps[client.Data.UUID] = server
		}
	}
	return true
}

//配置MQTT接收器
func (_this *CloudServer) mqttReceiver(key string, buffer []uint8) {
	if val, ok := _this.tcps[key]; ok {
		val.SendData(buffer)
	} else {
		logger.Warn("MQTT:" + key + "不存在或已删除")
	}
}

//配置TCP接收器
func (_this *CloudServer) tcpReceiver(key string, buffer []uint8) {
	_this.mqttConntion.SendData(key, buffer)
}

//启动MQTT线程
func (_this *CloudServer) mqttThreadStart() bool {
	go _this.mqttConntion.Start()
	return true
}

//启动TCP线程
func (_this *CloudServer) tcpThreadStart() bool {
	for _, tcp := range _this.tcps {
		go tcp.Start()
	}
	return true
}

//读取JSON文件
func (_this *CloudServer) jsonRead(jsonData string) {

}

//打开文件
func (_this *CloudServer) fileRead(filePath string) ([]byte, error) {
	return ioutil.ReadFile(filePath)
}

//根据协议创建
func (_this *CloudServer) protocolCreator(inMame string, protocol string, receiver func()) {

}
